package com.woniuxy.sale.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.model.entity.Goods;
import com.woniuxy.model.vo.GoodsVo;
import com.woniuxy.model.vo.UpdateSaleOrderVo;
import com.woniuxy.response.CustomPage;
import com.woniuxy.model.entity.ExportTable;
import com.woniuxy.sale.entity.dto.SaleOrderDTO;
import com.woniuxy.sale.entity.dto.SalePackDTO;
import com.woniuxy.sale.entity.dto.TopDTO;
import com.woniuxy.sale.entity.vo.*;
import com.woniuxy.sale.exception.SaleOrderAddException;
import com.woniuxy.sale.mapper.SaleOrderMapper;
import com.woniuxy.sale.service.ExportTableService;
import com.woniuxy.sale.service.SaleOrderItemService;
import com.woniuxy.sale.service.SaleOrderService;
import com.woniuxy.service.FeignGoodsService;
import com.woniuxy.util.SnowflakeIdWorker;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 选货单总表; 服务实现类
 * </p>
 *
 * @author lio
 * @since 2023-09-07
 */
@Service
@Slf4j
public class SaleOrderServiceImpl implements SaleOrderService {

    @Resource
    private SaleOrderMapper saleOrderMapper;

    @Resource
    private SaleOrderItemService saleOrderItemService;

    @Resource
    private FeignGoodsService feignGoodsService;

    @Resource
    private ExportTableService exportTableService;

    @Override
    public CustomPage<List<SaleOrderDTO>> info(SaleOrderVo saleOrderVo) {
        PageHelper.startPage(saleOrderVo.getCurrent(),saleOrderVo.getSize());

        List<SaleOrderDTO> saleOrderList = saleOrderMapper.info(saleOrderVo);
        PageInfo<SaleOrderDTO> pageInfo = new PageInfo<>(saleOrderList);

        CustomPage<List<SaleOrderDTO>> customPage = CustomPage.<List<SaleOrderDTO>>builder()
                .currentPage(saleOrderVo.getCurrent())
                .size(saleOrderVo.getSize())
                .totalPage(pageInfo.getPages())
                .total(pageInfo.getTotal())
                .data(saleOrderList)
                .build();
        log.debug(customPage.toString());
        return customPage;
    }

    @Override
    public CustomPage<List<GoodsVo>> findGoods(GoodsVo goodsVo) {
        return null;
    }

    @GlobalTransactional(rollbackFor = SaleOrderAddException.class)
    @Override
    public boolean add(AddSaleOrderVo saleOrderVo) throws SaleOrderAddException{
        //添加选货单信息
        //sno
        String sno = "XH" + SnowflakeIdWorker.newId();
        //总价
        BigDecimal totalPrice = new BigDecimal("0.0");
        //商品列表
        List<SaleAddOrderItemVo> orderItemVoList = new ArrayList<>();

        //查询所有商品信息 这块应该调用feign接口
        List<Goods> goodsList = feignGoodsService.findByListNumber(saleOrderVo.getGoodsList()).getData();

        //计算总价
        for (int i = 0; i < saleOrderVo.getGoodsList().size(); i++) {
            //得到重量
            BigDecimal weight = goodsList.get(i).getWeight();
            //得到数量
            Integer count = Integer.valueOf(saleOrderVo.getGoodsList().get(i).getCount()).intValue() ;
            //得到单价
            BigDecimal unitPrice = goodsList.get(i).getUnitPrice();
            //小计 单价*重量*数量
            BigDecimal small = unitPrice.multiply(weight).multiply(new BigDecimal(count));
            //累加
            totalPrice = totalPrice.add(small);

            //封装产品信息
            String states = "0";
            SaleAddOrderItemVo orderItemVo = new SaleAddOrderItemVo(goodsList.get(i),count,states);
            orderItemVoList.add(orderItemVo);
        }

        log.debug("选货单总价:" + totalPrice);

        //生成选货单
        SaleAddOrderVo orderVo = new SaleAddOrderVo(sno,saleOrderVo.getDepotId(),
                saleOrderVo.getCreator(),saleOrderVo.getCustomer(),totalPrice,orderItemVoList);

        if(!saleOrderMapper.add(orderVo)){
            throw new SaleOrderAddException("选货单新增失败,请重新填写!");
        }
        log.debug("订单编号:" + orderVo.getId());
        log.debug(orderItemVoList.toString());

        if(!saleOrderItemService.addItem(orderItemVoList)){
            throw new SaleOrderAddException("选货单单项表新增失败,请重新填写!");
        }

        return true;
    }

    @Transactional(rollbackFor = SaleOrderAddException.class)
    @Override
    public boolean updateState(UpdateSaleOrderVo updateSaleOrderVo) {
        //判断是否进入下个流程
        //查询sno的状态码
        String state = saleOrderMapper.findStateBySno(updateSaleOrderVo.getSno());
        //传入的状态比当前状态小,则不能修改状态
        if(Integer.valueOf(state).compareTo(Integer.valueOf(updateSaleOrderVo.getState())) > 0){
            throw new SaleOrderAddException("已进入下个流程,不能更改状态!");
        }

        return saleOrderMapper.updateState(updateSaleOrderVo);
    }

    @Transactional(rollbackFor = SaleOrderAddException.class)
    @Override
    public boolean del(DelSaleOrderVo delSaleOrderVo) {

        //判断选货单状态
        if(!"0".equals(delSaleOrderVo.getState()) && !"-1".equals(delSaleOrderVo.getState())){
            throw new SaleOrderAddException("选货单已进入下个流程,删除失败!");
        }

        //删除选货单 只有本人才能删除、只有未提交的才能删除
        if(!saleOrderMapper.del(delSaleOrderVo)){
            throw new SaleOrderAddException("选货单删除失败,没有权限!");
        }

        return true;
    }

    @Override
    public CustomPage<List<SalePackDTO>> packInfo(SaleOrderVo saleOrderVo) {
        PageHelper.startPage(saleOrderVo.getCurrent(),saleOrderVo.getSize());

        List<SalePackDTO> saleOrderList = saleOrderMapper.packInfo(saleOrderVo);
        PageInfo<SalePackDTO> pageInfo = new PageInfo<>(saleOrderList);

        CustomPage<List<SalePackDTO>> customPage = CustomPage.<List<SalePackDTO>>builder()
                .currentPage(saleOrderVo.getCurrent())
                .size(saleOrderVo.getSize())
                .totalPage(pageInfo.getPages())
                .total(pageInfo.getTotal())
                .data(saleOrderList)
                .build();
        log.debug(customPage.toString());
        return customPage;
    }

    @Override
    public SalePackDTO findAllBySno(String sno) {
        SaleOrderVo saleOrderVo = new SaleOrderVo();
        saleOrderVo.setSno(sno);
        return saleOrderMapper.packInfo(saleOrderVo).get(0);
    }

    @Transactional(rollbackFor = SaleOrderAddException.class)
    @Override
    public boolean check(UpdateSaleOrderVo updateSaleOrderVo) {
        String state = saleOrderMapper.findStateBySno(updateSaleOrderVo.getSno());
        if(!"1".equals(state)){
            throw new SaleOrderAddException("该选货单未进入审核流程,审核失败!");
        }
        return saleOrderMapper.updateState(updateSaleOrderVo);
    }

    @Override
    public List<String> findAllSno() {
        return saleOrderMapper.findAllSno();
    }

    @Override
    public String findCustomerBySno(String sno) {
        return saleOrderMapper.findCustomerBySno(sno);
    }

    @Transactional(rollbackFor = SaleOrderAddException.class)
    @Override
    public boolean updateSaleOrder(UpdateSaleOrderAllVo updateSaleOrderAllVo) {

        BigDecimal totalPrice = new BigDecimal("0.0");

        //查询所有商品信息 这块应该调用feign接口
        List<Goods> goodsList = feignGoodsService.findByListNumber(updateSaleOrderAllVo.getGoodsList()).getData();

        //计算总价
        for (int i = 0; i < updateSaleOrderAllVo.getGoodsList().size(); i++) {
            //得到重量
            BigDecimal weight = goodsList.get(i).getWeight();
            //得到数量
            Integer count = Integer.valueOf(updateSaleOrderAllVo.getGoodsList().get(i).getCount()).intValue() ;
            //得到单价
            BigDecimal unitPrice = goodsList.get(i).getUnitPrice();
            //小计 单价*重量*数量
            BigDecimal small = unitPrice.multiply(weight).multiply(new BigDecimal(count));
            //累加
            totalPrice = totalPrice.add(small);

            //修改产品数量
            UpdateSaleItemVo updateSaleItemVo = new UpdateSaleItemVo();
            updateSaleItemVo.setCount(updateSaleOrderAllVo.getGoodsList().get(i).getCount());
            updateSaleItemVo.setSid(updateSaleOrderAllVo.getSid());
            updateSaleItemVo.setGoodsNumber(updateSaleOrderAllVo.getGoodsList().get(i).getGoodsNumber());
            if(!saleOrderItemService.updateCountBySidAndNumber(updateSaleItemVo)){
                throw new SaleOrderAddException("产品" +
                        updateSaleOrderAllVo.getGoodsList().get(i).getGoodsNumber() + "数量修改失败!");
            }
        }

        log.debug("选货单总价:" + totalPrice);
        //修改选货单总价
        if(!saleOrderMapper.updatePriceById(totalPrice,updateSaleOrderAllVo.getSid())){
            throw new SaleOrderAddException("选货单总价修改失败!");
        }

        return false;
    }

    @Transactional
    @Override
    public boolean exportSaleOrder(ExportTable table) {
        return exportTableService.add(table);
    }

    @Override
    public Integer findSidBySno(String sno) {
        return saleOrderMapper.findSidBySno(sno);
    }

    @Override
    public List<TopDTO> findTopPaid() {
        return saleOrderMapper.findTopPaid();
    }

    @Override
    public List<TopDTO> findToUnpPaid() {
        return saleOrderMapper.findToUnpPaid();
    }

    @Override
    public BigDecimal findTotalPriceBySno(String sno) {
        return saleOrderMapper.findTotalPriceBySno(sno);
    }
}
